<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>复古水墨画</title>
    <style>
        body {
            font-family: 'SimSun', '宋体', serif;
            background-color: #fff;
            margin: 0;
            padding: 20px;
            color: #333;
            text-align: center;
        }
        .controls {
            display: flex;
            justify-content: center;
            gap: 20px;
            margin-bottom: 30px;
            flex-wrap: wrap;
        }
        .btn {
            color: #f1f1f1;
            border: none;
            padding: 12px 25px;
            cursor: pointer;
            border-radius: 4px;
            font-family: 'SimSun', '宋体', serif;
            font-size: 16px;
            letter-spacing: 1px;
            transition: all 0.3s;
        }
        #generateBtn {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        }
        #saveBtn {
            position: fixed;
            top: 50%;
            right: 20px;
            transform: translateY(-50%);
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            border: none;
            border-radius: 5px;
            padding: 10px 20px;
            cursor: pointer;
            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
            transition: background 0.3s ease;
        }

        #saveBtn:hover {
            background: linear-gradient(135deg, #5a6fc5 0%, #6b4293 100%);
        }
        #generateBtn:hover {
           background: linear-gradient(135deg, #5a6fc5 0%, #6b4293 100%);
        }
        canvas {
            background-color: #f9f5e9;
            border: 20px solid #d1c7b7;
            display: block;
            margin: 0 auto;
            box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
            max-width: 100%;
        }
        .loading {
            font-size: 18px;
            color: #666;
            margin: 20px 0;
            font-style: italic;
            display: none;
        }
        .options {
            display: flex;
            justify-content: center;
            gap: 15px;
            margin: 25px 0;
            flex-wrap: wrap;
        }
        .option-btn {
            background: none;
            border: 1px solid #ccc;
            padding: 8px 15px;
            cursor: pointer;
            border-radius: 20px;
            font-family: 'SimSun', '宋体', serif;
            transition: all 0.3s;
        }
        .option-btn.active {
            background-color: #764ba2;
            color: white;
            border-color: #764ba2;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="controls">
            <button class="option-btn active" data-technique="bamboo">墨竹</button>
            <button class="option-btn" data-technique="plum">寒梅</button>
            <button class="btn" id="generateBtn">生成</button>
            <button class="btn" id="saveBtn">绘画下载</button>
        </div>
        <div class="loading" id="loading">正在创作中，请稍候...</div>
        <canvas id="inkCanvas" width="800" height="600"></canvas>
    </div>
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            const canvas = document.getElementById('inkCanvas');
            const ctx = canvas.getContext('2d');
            const generateBtn = document.getElementById('generateBtn');
            const saveBtn = document.getElementById('saveBtn');
            const loading = document.getElementById('loading');
            const optionBtns = document.querySelectorAll('.option-btn');
            let currentTechnique = 'bamboo';
            function initCanvas() {
                ctx.fillStyle = '#f9f5e9';
                ctx.fillRect(0, 0, canvas.width, canvas.height);
                applyPaperTexture();
            }
            function applyPaperTexture() {
                ctx.fillStyle = '#f9f5e9';
                ctx.fillRect(0, 0, canvas.width, canvas.height);
                ctx.globalCompositeOperation = 'multiply';
                const textureImage = new Image();
                textureImage.src = createPaperTextureData();
                ctx.drawImage(textureImage, 0, 0, canvas.width, canvas.height);
                ctx.globalCompositeOperation = 'source-over';
            }
            function createPaperTextureData() {
                const textureCanvas = document.createElement('canvas');
                textureCanvas.width = 200;
                textureCanvas.height = 200;
                const textureCtx = textureCanvas.getContext('2d');
                for (let i = 0; i < 500; i++) {
                    const x = Math.random() * textureCanvas.width;
                    const y = Math.random() * textureCanvas.height;
                    const length = 1 + Math.random() * 3;
                    const angle = Math.random() * Math.PI * 2;
                    const alpha = 0.02 + Math.random() * 0.03;
                    textureCtx.strokeStyle = `rgba(120, 90, 60, ${alpha})`;
                    textureCtx.lineWidth = 0.5;
                    textureCtx.beginPath();
                    textureCtx.moveTo(x, y);
                    textureCtx.lineTo(
                        x + Math.cos(angle) * length,
                        y + Math.sin(angle) * length
                    );
                    textureCtx.stroke();
                }
                for (let i = 0; i < 100; i++) {
                    const x = Math.random() * textureCanvas.width;
                    const y = Math.random() * textureCanvas.height;
                    const radius = 0.5 + Math.random() * 2;
                    const alpha = 0.03 + Math.random() * 0.05;
                    textureCtx.fillStyle = `rgba(100, 80, 60, ${alpha})`;
                    textureCtx.beginPath();
                    textureCtx.arc(x, y, radius, 0, Math.PI * 2);
                    textureCtx.fill();
                }
                return textureCanvas.toDataURL();
            }
            function generateInkPainting() {
                loading.style.display = 'block';
                initCanvas();
                setTimeout(() => {
                    if (currentTechnique === 'bamboo') {
                        createBambooPainting();
                    } else {
                        createPlumPainting();
                    }
                    loading.style.display = 'none';
                }, 100);
            }
            function createBambooPainting() {
                const stalkCount = 3 + Math.floor(Math.random() * 3);
                for (let i = 0; i < stalkCount; i++) {
                    const x = canvas.width * 0.2 + i * (canvas.width * 0.6 / stalkCount);
                    const height = canvas.height * (0.5 + Math.random() * 0.3);
                    const y = canvas.height * 0.9 - height;
                    const opacity = 0.5 + Math.random() * 0.3;
                    drawBambooStalk(
                        x, 
                        y, 
                        height,
                        { r: 20, g: 20, b: 20 },
                        opacity,
                        2 + Math.random() * 2
                    );
                }
                const leafCount = 20 + Math.floor(Math.random() * 20);
                for (let i = 0; i < leafCount; i++) {
                    const x = canvas.width * 0.1 + Math.random() * canvas.width * 0.8;
                    const y = canvas.height * 0.2 + Math.random() * canvas.height * 0.6;
                    const size = canvas.height * (0.05 + Math.random() * 0.08);
                    const angle = Math.random() * Math.PI * 2;
                    const opacity = 0.4 + Math.random() * 0.4;
                    drawBambooLeaf(
                        x, y, size, angle,
                        { r: 15, g: 15, b: 15 },
                        opacity,
                        1 + Math.random()
                    );
                }
            }
            function drawBambooStalk(x, y, height, color, opacity, strokeWidth) {
                ctx.save();
                ctx.strokeStyle = `rgba(${color.r}, ${color.g}, ${color.b}, ${opacity})`;
                ctx.lineWidth = strokeWidth;
                ctx.lineJoin = 'round';
                ctx.lineCap = 'round';
                const segmentCount = 5 + Math.floor(Math.random() * 5);
                const segmentHeight = height / segmentCount;
                for (let i = 0; i < segmentCount; i++) {
                    const segmentY = y + i * segmentHeight;
                    const nextY = y + (i + 1) * segmentHeight;
                    const curve = (Math.random() - 0.5) * strokeWidth * 3;
                    ctx.beginPath();
                    ctx.moveTo(x, segmentY);
                    if (i === segmentCount - 1) {
                        ctx.lineTo(x, nextY);
                    } else {
                        ctx.quadraticCurveTo(
                            x + curve, 
                            segmentY + segmentHeight * 0.5,
                            x, 
                            nextY
                        );
                    }
                    ctx.stroke();
                    if (i < segmentCount - 1) {
                        ctx.beginPath();
                        ctx.arc(x, nextY, strokeWidth * 0.7, 0, Math.PI * 2);
                        ctx.fillStyle = `rgba(${color.r}, ${color.g}, ${color.b}, ${opacity * 1.5})`;
                        ctx.fill();
                        ctx.beginPath();
                        ctx.arc(x, nextY, strokeWidth * 0.7, Math.PI * 0.2, Math.PI * 0.8);
                        ctx.strokeStyle = `rgba(${color.r}, ${color.g}, ${color.b}, ${opacity * 0.8})`;
                        ctx.lineWidth = strokeWidth * 0.3;
                        ctx.stroke();
                    }
                }
                ctx.restore();
            }
            function drawBambooLeaf(x, y, size, angle, color, opacity, strokeWidth) {
                ctx.save();
                ctx.translate(x, y);
                ctx.rotate(angle);
                const gradient = ctx.createLinearGradient(0, -size * 0.2, size, 0);
                gradient.addColorStop(0, `rgba(${color.r}, ${color.g}, ${color.b}, ${opacity * 1.2})`);
                gradient.addColorStop(1, `rgba(${color.r}, ${color.g}, ${color.b}, ${opacity * 0.5})`);
                ctx.strokeStyle = gradient;
                ctx.fillStyle = `rgba(${color.r}, ${color.g}, ${color.b}, ${opacity * 0.4})`;
                ctx.lineWidth = strokeWidth;
                ctx.lineJoin = 'round';
                ctx.lineCap = 'round';
                ctx.beginPath();
                ctx.moveTo(0, 0);
                ctx.quadraticCurveTo(
                    size * 0.3, 
                    -size * 0.1, 
                    size * 0.9, 
                    0
                );
                ctx.stroke();
                ctx.beginPath();
                ctx.moveTo(size * 0.1, 0);
                ctx.quadraticCurveTo(
                    size * 0.4, 
                    -size * 0.3, 
                    size * 0.9, 
                    0
                );
                ctx.quadraticCurveTo(
                    size * 0.4, 
                    size * 0.3, 
                    size * 0.1, 
                    0
                );
                ctx.fill();
                ctx.beginPath();
                ctx.moveTo(size * 0.1, 0);
                ctx.quadraticCurveTo(
                    size * 0.4, 
                    -size * 0.3, 
                    size * 0.9, 
                    0
                );
                ctx.stroke();
                ctx.restore();
            }
            function createPlumPainting() {
                const branchCount = 1 + Math.floor(Math.random() * 2);
                for (let i = 0; i < branchCount; i++) {
                    drawPlumBranch(
                        canvas.width * 0.3 + Math.random() * canvas.width * 0.4,
                        canvas.height * 0.7 + Math.random() * canvas.height * 0.2,
                        canvas.height * 0.6,
                        { r: 30, g: 30, b: 30 },
                        0.7 + Math.random() * 0.2,
                        3 + Math.random() * 2
                    );
                }
                const flowerCount = 15 + Math.floor(Math.random() * 20);
                for (let i = 0; i < flowerCount; i++) {
                    const x = canvas.width * 0.1 + Math.random() * canvas.width * 0.8;
                    const y = canvas.height * 0.2 + Math.random() * canvas.height * 0.6;
                    const size = canvas.height * (0.03 + Math.random() * 0.05);
                    const opacity = 0.5 + Math.random() * 0.3;
                    drawPlumBlossom(
                        x, y, size,
                        { r: 30, g: 30, b: 30 },
                        opacity,
                        1 + Math.random()
                    );
                }
                if (Math.random() > 0.6) {
                    drawSnowEffect(
                        { r: 240, g: 240, b: 240 },
                        0.3 + Math.random() * 0.2
                    );
                }
            }
            function drawPlumBranch(x, y, length, color, opacity, strokeWidth) {
                ctx.save();
                ctx.strokeStyle = `rgba(${color.r}, ${color.g}, ${color.b}, ${opacity})`;
                ctx.lineWidth = strokeWidth;
                ctx.lineJoin = 'round';
                ctx.lineCap = 'round';
                const segments = 3 + Math.floor(Math.random() * 3);
                let currentX = x;
                let currentY = y;
                for (let i = 0; i < segments; i++) {
                    const segmentLength = length / segments;
                    const nextX = currentX - segmentLength * 0.8;
                    const nextY = currentY - segmentLength * 0.9;
                    const controlX = currentX - segmentLength * 0.4 + (Math.random() - 0.5) * segmentLength * 0.3;
                    const controlY = currentY - segmentLength * 0.5 + (Math.random() - 0.5) * segmentLength * 0.2;
                    const steps = 5 + Math.floor(Math.random() * 5);
                    for (let j = 0; j < steps; j++) {
                        const t1 = j / steps;
                        const t2 = (j + 0.8) / steps;
                        const x1 = currentX * (1 - t1) + controlX * t1;
                        const y1 = currentY * (1 - t1) + controlY * t1;
                        const x2 = currentX * (1 - t2) + controlX * t2;
                        const y2 = currentY * (1 - t2) + controlY * t2;
                        const x3 = controlX * (1 - t1) + nextX * t1;
                        const y3 = controlY * (1 - t1) + nextY * t1;
                        const x4 = controlX * (1 - t2) + nextX * t2;
                        const y4 = controlY * (1 - t2) + nextY * t2;
                        ctx.beginPath();
                        ctx.moveTo(x1, y1);
                        ctx.quadraticCurveTo(x2, y2, x4, y4);
                        ctx.stroke();
                    }
                    currentX = nextX;
                    currentY = nextY;
                }
                ctx.lineWidth = strokeWidth * 0.7;
                const sideBranches = 3 + Math.floor(Math.random() * 3);
                for (let i = 0; i < sideBranches; i++) {
                    const branchPos = 0.2 + Math.random() * 0.6;
                    const branchLength = length * (0.2 + Math.random() * 0.3);
                    const t = branchPos;
                    const mainX = x - (length * 0.8) * t;
                    const mainY = y - (length * 0.9) * t;
                    const angle = -Math.PI/4 + Math.random() * Math.PI/2;
                    const endX = mainX + Math.cos(angle) * branchLength;
                    const endY = mainY + Math.sin(angle) * branchLength;
                    const steps = 3 + Math.floor(Math.random() * 3);
                    for (let j = 0; j < steps; j++) {
                        const t1 = j / steps;
                        const t2 = (j + 0.8) / steps;
                        const x1 = mainX * (1 - t1) + endX * t1;
                        const y1 = mainY * (1 - t1) + endY * t1;
                        const x2 = mainX * (1 - t2) + endX * t2;
                        const y2 = mainY * (1 - t2) + endY * t2;
                        ctx.beginPath();
                        ctx.moveTo(x1, y1);
                        ctx.lineTo(x2, y2);
                        ctx.stroke();
                    }
                }
                ctx.restore();
            }
            function drawPlumBlossom(x, y, size, color, opacity, strokeWidth) {
                ctx.save();
                ctx.translate(x, y);
                ctx.rotate(Math.random() * Math.PI * 2);
                ctx.beginPath();
                ctx.arc(0, 0, size * 0.15, 0, Math.PI * 2);
                ctx.fillStyle = `rgba(${color.r}, ${color.g}, ${color.b}, ${opacity * 1.5})`;
                ctx.fill();
                for (let i = 0; i < 5 + Math.floor(Math.random() * 5); i++) {
                    const angle = Math.random() * Math.PI * 2;
                    const radius = size * 0.1 + Math.random() * size * 0.05;
                    ctx.beginPath();
                    ctx.arc(
                        Math.cos(angle) * radius * 0.5,
                        Math.sin(angle) * radius * 0.5,
                        size * 0.03,
                        0,
                        Math.PI * 2
                    );
                    ctx.fillStyle = `rgba(${color.r}, ${color.g}, ${color.b}, ${opacity * 1.8})`;
                    ctx.fill();
                }
                for (let i = 0; i < 5; i++) {
                    const angle = (i * Math.PI * 2 / 5);
                    const petalOpacity = opacity * (0.7 + Math.random() * 0.3);
                    const petalSize = size * (0.8 + Math.random() * 0.3);
                    ctx.beginPath();
                    ctx.ellipse(
                        Math.cos(angle) * size * 0.5, 
                        Math.sin(angle) * size * 0.5,
                        petalSize * 0.5, 
                        petalSize * 0.3, 
                        angle, 
                        0, 
                        Math.PI * 2
                    );
                    ctx.fillStyle = `rgba(${color.r}, ${color.g}, ${color.b}, ${petalOpacity * 0.4})`;
                    ctx.fill();
                    if (Math.random() > 0.3) {
                        ctx.beginPath();
                        ctx.ellipse(
                            Math.cos(angle) * size * 0.5, 
                            Math.sin(angle) * size * 0.5,
                            petalSize * 0.5, 
                            petalSize * 0.3, 
                            angle, 
                            Math.PI * 0.2, 
                            Math.PI * 0.8
                        );
                        ctx.strokeStyle = `rgba(${color.r}, ${color.g}, ${color.b}, ${petalOpacity * 0.8})`;
                        ctx.lineWidth = strokeWidth * 0.5;
                        ctx.stroke();
                    }
                }
                ctx.beginPath();
                ctx.moveTo(0, size * 0.1);
                ctx.lineTo(size * 0.1, size * 0.15);
                ctx.moveTo(0, size * 0.1);
                ctx.lineTo(-size * 0.1, size * 0.15);
                ctx.strokeStyle = `rgba(${color.r}, ${color.g}, ${color.b}, ${opacity * 0.8})`;
                ctx.lineWidth = strokeWidth * 0.7;
                ctx.stroke();
                ctx.restore();
            }
            function drawSnowEffect(color, opacity) {
                ctx.save();
                for (let i = 0; i < 30 + Math.random() * 50; i++) {
                    const flakeX = Math.random() * canvas.width;
                    const flakeY = Math.random() * canvas.height;
                    const flakeSize = 1 + Math.random() * 2;
                    ctx.beginPath();
                    ctx.arc(flakeX, flakeY, flakeSize, 0, Math.PI * 2);
                    ctx.fillStyle = `rgba(${color.r}, ${color.g}, ${color.b}, ${opacity * (0.5 + Math.random() * 0.5)})`;
                    ctx.fill();
                }
                ctx.restore();
            }
            generateBtn.addEventListener('click', generateInkPainting);
            saveBtn.addEventListener('click', () => {
                const link = document.createElement('a');
                link.download = '水墨画.png';
                link.href = canvas.toDataURL('image/png');
                link.click();
            });
            optionBtns.forEach(btn => {
                btn.addEventListener('click', function() {
                    optionBtns.forEach(b => b.classList.remove('active'));
                    this.classList.add('active');
                    currentTechnique = this.dataset.technique;
                });
            });
            initCanvas();
        });
    </script>
</body>
</html>
